local M = {
  -- 该插件依赖 nvim-treesitter 插件
  "kevinhwang91/nvim-ufo",
  enabled = true,
  -- cmd = { "UfoDisable", "UfoEnable" },
  event = "VeryLazy",
  dependencies = {
    "kevinhwang91/promise-async",
    {
      "luukvbaal/statuscol.nvim",
      -- event = { "BufReadPre, BufNewFile", "FileReadPost" },
      event = "VeryLazy",
      config = function()
        local builtin = require "statuscol.builtin"
        require("statuscol").setup {
          relculright = true,
          segments = {
            { text = { builtin.foldfunc }, click = "v:lua.ScFa" },
            { text = { "%s" }, click = "v:lua.ScSa" },
            { text = { builtin.lnumfunc, " " }, click = "v:lua.ScLa" },
          },
        }
      end,
    },
    {
      "anuvyklack/fold-preview.nvim",
      event = { "BufReadPost", "BufNewFile", "FileReadPost" },
      enabled = true,
      dependencies = "anuvyklack/keymap-amend.nvim",
      config = true,
    },
  },
}
function M.config()
  local status, nvim_ufo = pcall(require, "ufo")
  if not status then
    vim.notify "Not found 'nvim-ufo' plugin"
    return
  end

  vim.o.foldcolumn = "1" -- '0' is not bad
  vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value
  vim.o.foldlevelstart = 99
  vim.o.foldenable = true

  vim.cmd [[highlight AdCustomFold guifg=#bf8040]]
  local handler = function(virtText, lnum, endLnum, width, truncate)
    local newVirtText = {}
    local suffix = ("  %d "):format(endLnum - lnum)
    local sufWidth = vim.fn.strdisplaywidth(suffix)
    local targetWidth = width - sufWidth
    local curWidth = 0

    for _, chunk in ipairs(virtText) do
      local chunkText = chunk[1]
      local chunkWidth = vim.fn.strdisplaywidth(chunkText)
      if targetWidth > curWidth + chunkWidth then
        table.insert(newVirtText, chunk)
      else
        chunkText = truncate(chunkText, targetWidth - curWidth)
        local hlGroup = chunk[2]
        table.insert(newVirtText, { chunkText, hlGroup })
        chunkWidth = vim.fn.strdisplaywidth(chunkText)
        -- str width returned from truncate() may less than 2nd argument, need padding
        if curWidth + chunkWidth < targetWidth then
          suffix = suffix .. (" "):rep(targetWidth - curWidth - chunkWidth)
        end
        break
      end
      curWidth = curWidth + chunkWidth
    end

    -- Second line
    local lines = vim.api.nvim_buf_get_lines(0, lnum, lnum + 1, false)
    local secondLine = nil
    if #lines == 1 then
      secondLine = lines[1]
    elseif #lines > 1 then
      secondLine = lines[2]
    end
    if secondLine ~= nil then
      table.insert(newVirtText, { secondLine, "AdCustomFold" })
    end

    table.insert(newVirtText, { suffix, "MoreMsg" })

    return newVirtText
  end

  nvim_ufo.setup {
    provider_selector = function(bufnr, filetype, buftype)
      return { "indent", "treesitter" } -- treesitter 表示需要 nvim-treesitter 插件支持
    end,
    fold_virt_text_handler = handler,
  }

  vim.keymap.set("n", "zR", function()
    nvim_ufo.openAllFolds()
  end, { desc = "Open All Folds" })
  vim.keymap.set("n", "zM", function()
    nvim_ufo.closeAllFolds()
  end, { desc = "Close All Folds" })

  -- keymap["ou"] = { "+Ufo" }
  -- keymap["oud"] = { "<cmd>UfoDisable<cr>", "Disable Ufo" }
  -- keymap["oue"] = { "<cmd>UfoEnable<cr>", "Enable Ufo" }

  -- vim.keymap.set("n", "zR", require("ufo").openAllFolds)
  -- vim.keymap.set("n", "zM", require("ufo").closeAllFolds)
  -- vim.keymap.set("n", "zr", require("ufo").openFoldsExceptKinds)
  -- vim.keymap.set("n", "zm", require("ufo").closeFoldsWith) -- closeAllFolds == closeFoldsWith(0)
  -- vim.keymap.set("n", "B", function()
  --     local winid = require("ufo").peekFoldedLinesUnderCursor()
  --     if not winid then
  --         -- choose one of coc.nvim and nvim lsp
  --         vim.lsp.buf.hover()
  --     end
  -- end)

  -- za：切换当前光标下的代码块的折叠状态。
  -- zA：递归切换当前光标下的所有代码块的折叠状态。
  -- zc：关闭当前光标下的代码块。
  -- zC：递归关闭当前光标下的所有代码块。
  -- zo：打开当前光标下的代码块。
  -- zO：递归打开当前光标下的所有代码块。
  -- zm：折叠所有代码块。
  -- zM：递归折叠所有代码块。
  -- zr：展开所有代码块。
  -- zR：递归展开所有代码块。
end

return M
